package main

import "fmt"

//函数定义：func关键字 函数名（接受参数） (返回值) {函数体}
//其中 函数名(接受参数)(返回值)，有个专业术语叫方法签名
func intSum(x, y int) int {
	a := x + y
	return a
}

//返回值可以给变量名
//当return后没有变量的情况下，默认会把res返回
func intSum2(x, y int) (res int) {
	res = x + y
	return // return res
}

//闭包函数
//特性1：返回值是个匿名函数
//特性2：在函数外部访问函数内部的环境和变量成为可能
//特性3：执行过程中，如果给闭包函数赋值，那么会发生内存逃逸，逃到堆上（内存不释放）
func AddInt() func(i int) int {
	var num int
	return func(i int) int {
		num += 1
		return num
	}
}

func main() {
	r := intSum2(5, 10)
	fmt.Println(r)

	//匿名函数
	test_fun := func(n1, n2 int) int {
		return n1 - n2
	}
	res := test_fun(2, 1)
	fmt.Println(res)
	//匿名函数不通过变量名使用，而是直接使用
	res1 := func(n1, n2 int) int {
		return n1 - n2
	}(3, 1)
	fmt.Println(res1)

	//闭包函数
	//第一种用法
	fmt.Println(AddInt()(1)) //AddInt() = func(i int) int {}
	//第二种用法，会发生内存逃逸
	fn := AddInt()
	fmt.Println("fn", fn(1))
	fmt.Println("fn", fn(1))
	fmt.Println("fn", fn(1))
}
